/**
 * 验证数据是否是 String 类型数据
 * @param {Any} variable 要验证的数据
 * @returns {Boolean} true: 是 String 类型数据；false: 不是 String 类型数据；
 */
export const isString = (variable) => typeof variable === "string";

/**
 * 验证数据是否是 Array 类型数据
 * @param {Any} variable 要验证的数据
 * @returns {Boolean} true: 是 Array 类型数据；false: 不是 Array 类型数据；
 */
export const isArray = (variable) => Array.isArray(variable);

/**
 * 验证数据是否是 Array 类型数据
 * Tips: 不包括数组、函数、null等
 * @param {Object} variable 要验证的数据
 * @returns {Boolean} true: 是 Object 类型数据；false: 不是 Object 类型数据；
 */
export const isObject = (variable) => {
    // 排除 null 和非对象类型
    if (variable === null || typeof variable !== "object") return false;

    // 使用 Object.prototype.toString.call 来获取变量的真实类型
    // 注意这里需要排除函数类型，因为函数在JavaScript中也是对象，但通常我们不希望将它们视为普通对象
    return Object.prototype.toString.call(variable) === "[object Object]";
};

/**
 * 验证数据是否是 Function 类型数据
 * @param {Any} variable 需要验证的数据
 * @returns {Boolean} true: 是Function 类型数据；false: 不是Function 类型数据；
 */
export const isFunction = (variable) => Object.prototype.toString.call(variable) === "[object Function]";

/**
 * 校验 URL 是否是绝对 URL
 * Tips: 如果 URL 以 “<scheme>：//” 或 “//”（协议相对URL）开头，则认为它是绝对的，RFC 3986 将方案名称定义为以字母开头的字符序列，然后是字母，数字，加号，句点或连字符的任意组合
 * @param {String} url 需要校验的 URL
 * @returns {Boolean} true: 是绝对 URL；false: 不是绝对 URL
 *
 */
export const isAbsoluteURL = (url = "") => /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);

/**
 * 深度合并两个对象
 * @param {Object} object1 对象一
 * @param {Object} object2 对象二
 * @returns {Object} 合并后的新对象数据，不影响原对象
 */
export function objectDeepMerge(object1, object2) {
    let merged = Object.assign({}, object1);
    for (let key in object2) {
        if (object2.hasOwnProperty(key)) {
            if (isObject(object2[key]) && !isArray(object2[key])) {
                if (isObject(merged[key]) && !isArray(merged[key])) {
                    merged[key] = objectDeepMerge(merged[key], object2[key]);
                } else {
                    merged[key] = Object.assign({}, object2[key]);
                }
            } else {
                merged[key] = object2[key];
            }
        }
    }
    return merged;
}

/**
 * 合并基准 URL 和相对 URL 成一个完整的 URL
 * @param {String} baseURL 基准 URL
 * @param {String} relativeURL 相对 URL
 * @returns {String} 返回合并后的 URL
 */
export const urlCombine = (baseURL = "", relativeURL = "") => {
    if (isAbsoluteURL(relativeURL)) return relativeURL;
    if (relativeURL && isString(relativeURL) && isString(baseURL)) {
        return baseURL.replace(/\/+$/, "") + "/" + relativeURL.replace(/^\/+/, "");
    }
    return baseURL;
};
